﻿// Partial Copyright (c) LogoUI Software Solutions LTD
// Author: Vladislav Spivak
// This source file is the part of LogoFX Framework http://logofx.codeplex.com
// See accompanying licences and credits.

//based on, but not limited to http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2010/03/09/mef-and-the-deploymentcatalog.aspx

#if SILVERLIGHT
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Windows.Markup;
using System.ComponentModel.Composition.Primitives;
using MefContrib.Hosting.Generics;

namespace LogoFX.Composition
{
    [ContentProperty("CatalogConfig")]
    public partial class DeploymentCatalogLoader
    {
        AggregateCatalog _aggregateCatalog;

        public DeploymentCatalogConfig CatalogConfig { get; set; }

        public CompositionContainer LoadCatalogConfigAsync(
          ComposablePartCatalog catalog, bool isThreadSafe, params ExportProvider[] exportProviders)
        {
            this._aggregateCatalog = new AggregateCatalog();

            if (catalog != null)
            {
                CacheCatalog(catalog);
            }

            CompositionContainer container = new CompositionContainer(
              this._aggregateCatalog, isThreadSafe, exportProviders);

            container.ComposeParts(new AggregateCatalogProvider()
            {
                Catalog = this._aggregateCatalog
            });

            if (this.CatalogConfig != null)
            {
                ConfigLoadHelper loadHelper = new ConfigLoadHelper(this.CatalogConfig);
                loadHelper.LoadAsync(OnLoaded, OnGroupLoaded, OnItemLoaded);
            }
            else
            {
                OnLoaded(new DeploymentCatalogConfig());
            }

            return (container);
        }
        public CompositionContainer LoadCatalogConfigAsync(
          ComposablePartCatalog catalog, params ExportProvider[] exportProviders)
        {
            return (LoadCatalogConfigAsync(catalog, false, exportProviders));
        }
        public CompositionContainer LoadCatalogConfigAsync(
          params ExportProvider[] exportProviders)
        {
            return (LoadCatalogConfigAsync(null, exportProviders));
        }
        public CompositionContainer LoadCatalogConfigAsync()
        {
            return (LoadCatalogConfigAsync((ComposablePartCatalog)null));
        }

        public void OnLoaded(DeploymentCatalogConfig config)
        {
            if (ConfigLoaded != null)
            {
                ConfigLoaded(config, EventArgs.Empty);
            }
        }

        public void OnGroupLoaded(DeploymentCatalogConfigGroup group)
        {
            if (ConfigGroupLoaded != null)
            {
                ConfigGroupLoaded(group, EventArgs.Empty);
            }
        }

        public void OnItemLoaded(DeploymentCatalogConfigItem item,
          DeploymentCatalog catalog, Exception error)
        {

            if (error == null)
            {
                CacheCatalog(catalog);
            }
            if (ConfigItemLoaded != null)
            {
                ConfigItemLoaded(item, new CatalogItemLoadedEventArgs()
                {
                    Error = error
                });
            }
        }

        private void CacheCatalog(ComposablePartCatalog catalog)
        {
            this._aggregateCatalog.Catalogs.Add(new GenericCatalog(catalog));

            if(CatalogCached!=null)
            {
                CatalogCached(this, new CatalogItemCachedEventArgs(catalog));
            }
        }

        public event EventHandler<CatalogItemLoadedEventArgs> ConfigItemLoaded;
        public event EventHandler ConfigGroupLoaded;
        public event EventHandler ConfigLoaded;
        public event EventHandler<CatalogItemCachedEventArgs> CatalogCached;

    }

}
#endif

